package com.echo.activity;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.activeandroid.ActiveAndroid;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapOptions;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.echo.SportsApplication;
import com.echo.dialog.AlertDialog;
import com.echo.model.Sport;
import com.echo.model.SportPoint;
import com.echo.service.MusicService;
import com.echo.util.DateUtil;
import com.echo.util.DrawableUtil;
import com.echo.util.TimeUtil;
import com.google.gson.Gson;
import com.truizlop.fabreveallayout.FABRevealLayout;
import com.truizlop.fabreveallayout.OnRevealChangeListener;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;


public class SportActivity extends AppCompatActivity implements LocationSource,AMapLocationListener {

    private Toolbar mToolbar;
    private TextView mToobarTitle;

    private MapView mMapView;
    private AMap mMap;
    private OnLocationChangedListener mListener;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;

    private FABRevealLayout mFabRevealLayout;
    private FloatingActionButton mFabMusicButton,mFabCameraButton;

    private PolylineOptions mPolylineOptions;
    private List<Polyline> mPolylines=new ArrayList<>();
    private Polyline mPolyline;
    private List<LatLng> mLatList=new ArrayList<>();

    private double mMaxLatitude,mMinLatitude,mMaxLongtitude,mMinLongtitude;

    private List<SportPoint> mSportPoints=new ArrayList<>();

    private LatLng preLat,curLat;

    private TextView mSportDistance,mSportTime,mSportSpeed,mSportCalories;

    private int mDistance=0;
    private float mSpeed=0;
    private int mTime=0;
    private int mCalories=0;

    private TimerTask mTask;
    private Timer mTimer;

    private boolean mRunning=false;
    private int mStart=0;

    private Button mStartButton,mEndButton;

    private Sport mSport;

    private LinearLayout mTypesLayout;
    private ImageView mTypeRun,mTypeRide,mTypeClimb;
    private int mType;


    private MusicService mService;
    private boolean mBind=false;
    private SeekBar mProgress;
    private TextView mSongTitle;
    private ImageView mPlayPauseButton;

    private Handler mTimeHandler=new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            mTime+=1;
            mSportTime.setText(TimeUtil.secondsToStr(mTime));
            return false;
        }
    });

    private Handler mSportHandler=new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            mSportDistance.setText(String.valueOf(mDistance)+" m");
            mSportSpeed.setText(String.valueOf(mSpeed));
            mSportCalories.setText(String.valueOf(mCalories));
            return false;
        }
    });

    private Handler mFinishHandler=new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            mSport.save();
            finish();
            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sport);

        mMapView = (MapView) findViewById(R.id.map);
        mMapView.onCreate(savedInstanceState);
        mMap = mMapView.getMap();

        initView();
        initSportView();
        initActionBar();
        initMap();
        //initLocation();
        initFabLayout();

        mTask = new TimerTask(){
            public void run() {
                if(mRunning) {
                    Message message = new Message();
                    message.what = 1;
                    mTimeHandler.sendMessage(message);
                }
            }
        };

    }

    private ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub
            mBind=false;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
            MusicService.MusicBinder binder = (MusicService.MusicBinder)service;
            mService = binder.getService();
            mBind=true;
            mService.setOnProgressListener(new MusicService.OnProgressListener() {
                @Override
                public void onProgress(int progress) {
                    mProgress.setProgress(progress);
                }
            });
            mService.setOnMusicChangeListener(new MusicService.OnMusicChangeListener() {
                @Override
                public void onMusicChange(String name) {
                    mSongTitle.setText(name);
                    mProgress.setProgress(0);
                }
            });
        }
    };

    private void initView() {
        mStartButton= (Button) findViewById(R.id.sport_start_button);
        mStartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                start_sport();
            }
        });
        mEndButton= (Button) findViewById(R.id.sport_end_button);
        mEndButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                end_sport();
            }
        });
        mTypesLayout= (LinearLayout) findViewById(R.id.sport_types_layout);
        mTypeRun= (ImageView) findViewById(R.id.type_run);
        mTypeRide= (ImageView) findViewById(R.id.type_ride);
        mTypeClimb= (ImageView) findViewById(R.id.type_climb);
        mTypeRun.setImageDrawable(DrawableUtil.tintListDrawable(mTypeRun.getDrawable(), getResources().getColorStateList(R.color.tab_tint)));
        mTypeRide.setImageDrawable(DrawableUtil.tintListDrawable(mTypeRide.getDrawable(), getResources().getColorStateList(R.color.tab_tint)));
        mTypeClimb.setImageDrawable(DrawableUtil.tintListDrawable(mTypeClimb.getDrawable(), getResources().getColorStateList(R.color.tab_tint)));
        mTypeRun.setTag(0);
        mTypeRide.setTag(1);
        mTypeClimb.setTag(2);
        mTypeRun.setOnClickListener(new TypeListener());
        mTypeRide.setOnClickListener(new TypeListener());
        mTypeClimb.setOnClickListener(new TypeListener());
        mTypeRun.setSelected(true);
        mProgress= (SeekBar) findViewById(R.id.song_progress_bar);
        mProgress.setMax(100);
        mSongTitle= (TextView) findViewById(R.id.song_title_text);
        mPlayPauseButton= (ImageView) findViewById(R.id.play_pause);
        mPlayPauseButton.setSelected(false);
    }

    private class TypeListener implements android.view.View.OnClickListener{

        @Override
        public void onClick(View v) {
            mType= (int) v.getTag();
            mTypeRun.setSelected(mType==0);
            mTypeRide.setSelected(mType==1);
            mTypeClimb.setSelected(mType==2);
        }
    }

    public void start_sport(){
        if(!mRunning) {
            if (mStart++ == 0) {
                mTimer=new Timer(true);
                mTimer.schedule(mTask,1000,1000);
                mSport=new Sport();
                mSport.setId(Calendar.getInstance().getTime().getTime());
                if(SportsApplication.getInstance().isLogin())
                    mSport.setId(SportsApplication.getInstance().getUserId());
                mSport.setDate(DateUtil.getDateStr(Calendar.getInstance()));
                mSport.setStart(Calendar.getInstance());
                mSport.setType(mType);
                mTypesLayout.setVisibility(View.GONE);
            }
            mRunning = true;
            mPolylineOptions=null;
            mStartButton.setText("暂停");
            mToobarTitle.setText("运动中");
        }else{
            mStartButton.setText("继续");
            mRunning=false;
            mToobarTitle.setText("休息");
        }
    }
    
    public void end_sport(){
        AlertDialog dialog=new AlertDialog(this);
        dialog.setMsg("是否结束本次运动?");
        dialog.setPositiveButton("", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mRunning=false;
                save();
                getSnapShot();
                //finish();
            }
        }).setNegativeButton("", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        dialog.show();
    }

    private void getSnapShot(){
        if(mStart!=0){
            LatLng southwest=new LatLng(mMinLatitude,mMinLongtitude);
            LatLng northeast=new LatLng(mMaxLatitude,mMaxLongtitude);
            LatLngBounds LatLngBounds=new LatLngBounds(southwest,northeast);
            mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(LatLngBounds,10));
            mMap.getMapScreenShot(new AMap.OnMapScreenShotListener() {
                @Override
                public void onMapScreenShot(Bitmap bitmap) {
                    if(mSport!=null) {
                        int size = bitmap.getWidth() * bitmap.getHeight() * 4;
                        ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
                        bitmap.compress(Bitmap.CompressFormat.PNG, 50, baos);
                        byte[] image = baos.toByteArray();
                        mSport.setSnapshot(image);
                        mFinishHandler.sendEmptyMessage(0);
                    }
                }

                @Override
                public void onMapScreenShot(Bitmap bitmap, int i) {

                }
            });
        }
    }

    private void save(){
        if(mSport!=null){
            mSport.setTime(mTime);
            mSport.setCalories(mCalories);
            mSport.setDistance(mDistance);
            //mSport.save();
        }
    }

    private void initSportView() {
        mSportDistance= (TextView) findViewById(R.id.sport_distance);
        mSportTime= (TextView) findViewById(R.id.sport_time);
        mSportSpeed= (TextView) findViewById(R.id.sport_speed);
        mSportCalories= (TextView) findViewById(R.id.sport_calories);
    }

    private void initFabLayout() {
        mFabRevealLayout= (FABRevealLayout) findViewById(R.id.fab_layout);
        mFabRevealLayout.setOnRevealChangeListener(new OnRevealChangeListener() {
            @Override
            public void onMainViewAppeared(FABRevealLayout fabRevealLayout, View mainView) {}

            @Override
            public void onSecondaryViewAppeared(final FABRevealLayout fabRevealLayout, View secondaryView) {
                prepareBackTransition(fabRevealLayout);
            }
        });
        mFabMusicButton= (FloatingActionButton) findViewById(R.id.fab_music_button);
        mFabCameraButton= (FloatingActionButton) findViewById(R.id.fab_camera_button);
        mFabCameraButton.setLeft(mFabMusicButton.getRight());
        mFabCameraButton.setRight(mFabMusicButton.getLeft());
    }

    private void prepareBackTransition(final FABRevealLayout fabRevealLayout) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                fabRevealLayout.revealMainView();
            }
        }, 2000);
    }

    private void initLocation() {
        // 自定义系统定位小蓝点
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        //myLocationStyle.myLocationIcon(BitmapDescriptorFactory
        //        .fromResource(R.mipmap.location_marker));// 设置小蓝点的图标
        myLocationStyle.strokeColor(Color.TRANSPARENT);// 设置圆形的边框颜色
        myLocationStyle.radiusFillColor(Color.TRANSPARENT);// 设置圆形的填充颜色
        // myLocationStyle.anchor(int,int)//设置小蓝点的锚点
        //myLocationStyle.strokeWidth(1.0f);// 设置圆形的边框粗细
        mMap.setMyLocationStyle(myLocationStyle);
        mMap.setLocationSource(this);// 设置定位监听
        //mMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        mMap.getUiSettings().setZoomControlsEnabled(false);
        mMap.getUiSettings().setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_CENTER);
        mMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        mMap.setMyLocationType(AMap.MAP_TYPE_NAVI);
    }

    private void initMap() {
        initLocation();
        mMap.animateCamera(CameraUpdateFactory.zoomTo(17));
    }

    private void initActionBar() {
        //From datas=new Select().from(DayData.class);
        mToolbar = (Toolbar) findViewById(R.id.sport_toolbar);
        mToobarTitle = (TextView) findViewById(R.id.sport_toolbar_title);
        mToobarTitle.setText("休息");
        mToobarTitle.setTextColor(Color.parseColor("#8a041835"));
        mToolbar.setTitle("");
        /*mToolbar.setNavigationIcon(
                DrawableUtil.tintDrawable(getResources()
                        .getDrawable(R.mipmap.ic_arrow_back_black_36dp),Color.parseColor("#8a041835")));*/
        setSupportActionBar(mToolbar);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mMapView.onPause();
        deactivate();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {

        super.onSaveInstanceState(outState);
        mMapView.onSaveInstanceState(outState);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (mListener != null && aMapLocation != null) {
            if (aMapLocation != null
                    && aMapLocation.getErrorCode() == 0) {
                mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点
                double latitude=aMapLocation.getLatitude(),longitude=aMapLocation.getLongitude();
                curLat = new LatLng(latitude, longitude);
                if(mRunning) {
                    if (mPolylineOptions == null) {
                        mPolylineOptions = new PolylineOptions();
                        mPolylineOptions.width(5);
                        mPolylineOptions.color(Color.parseColor("#84be1e"));
                        mPolyline = mMap.addPolyline(mPolylineOptions);
                        mPolylines.add(mPolyline);
                        if(mMaxLatitude==0){
                            mMaxLatitude=latitude;
                            mMinLatitude=latitude;
                            mMaxLongtitude=longitude;
                            mMinLongtitude=longitude;
                        }
                    }
                    mLatList.add(curLat);
                    mPolyline.setPoints(mLatList);
                    if (preLat != null)
                        mDistance += (int) AMapUtils.calculateLineDistance(preLat, curLat);
                    mSpeed = aMapLocation.getSpeed();
                    Message message = new Message();
                    message.what = 1;
                    mSportHandler.sendMessage(message);
                    if(latitude>mMaxLatitude)
                        mMaxLatitude=latitude;
                    if(latitude<mMinLatitude)
                        mMinLatitude=latitude;
                    if(longitude>mMaxLongtitude)
                        mMaxLongtitude=longitude;
                    if(longitude<mMinLongtitude)
                        mMinLongtitude=longitude;
                }
                preLat = curLat;
            } else {
                String errText = "定位失败," + aMapLocation.getErrorCode() + ": " + aMapLocation.getErrorInfo();
                Log.e("AmapErr", errText);
            }
        }
    }

    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
        if (mlocationClient == null) {
            mlocationClient = new AMapLocationClient(this);
            mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mlocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            mLocationOption.setInterval(100);
            mLocationOption.setGpsFirst(true);
            //设置定位参数
            mlocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mlocationClient.startLocation();
        }
    }

    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            AlertDialog dialog=new AlertDialog(this);
            dialog.setMsg("是否结束本次运动?");
            dialog.setPositiveButton("", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            }).setNegativeButton("", new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });
            dialog.show();
        }
        return false;
    }

    public void sport_previous(View view) throws IOException {
        if(mBind){
            mService.pre();
        }else{
            startMusicService();
        }
    }

    public void sport_play_pause(View view) throws IOException {
        if(mBind){
            mService.play();
            if(mPlayPauseButton.isSelected()) {
                mPlayPauseButton.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ic_play_arrow_black_36dp));
                mPlayPauseButton.setSelected(false);
            }
            else {
                mPlayPauseButton.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_pause_black_48dp));
                mPlayPauseButton.setSelected(true);
            }
        }else{
            startMusicService();
        }
    }

    public void sport_next(View view) throws IOException {
        if(mBind){
            mService.next();
        }else{
            startMusicService();
        }
    }

    private void startMusicService(){

        Intent intent=new Intent(SportActivity.this, MusicService.class);
        bindService(intent,conn, Context.BIND_AUTO_CREATE);
    }

    public void to_camera(View view){
        Intent intent=new Intent(SportActivity.this,CameraActivity.class);
        startActivity(intent);
    }
}
